#include "InputKeyboard.h"
#include "Visualisation.h"
#include "UserInterface.h"
#include "WorldModel.h"

CInputKeyboard::CInputKeyboard(void):m_diKeyboardDevice(0)
{
}

CInputKeyboard::~CInputKeyboard(void)
{
	if (m_diKeyboardDevice)
	{
		m_diKeyboardDevice->Unacquire();
		m_diKeyboardDevice->Release();
	}
}

bool CInputKeyboard::initialise(const LPDIRECTINPUT8 diObject)
{
	//create the device object that represent the keyboard
	HRESULT hr = diObject->CreateDevice(GUID_SysKeyboard, &m_diKeyboardDevice, NULL);
	if(FAILED(hr))
		return false;

	//keyboard device format
	hr=m_diKeyboardDevice->SetDataFormat(&c_dfDIKeyboard);
	if(FAILED(hr))
		return false;

	//keyboard behaviour
	hr = m_diKeyboardDevice->SetCooperativeLevel(VIS->getWindowHandle(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	if(FAILED(hr))
		return false;

	//acquire the keyboard device
	hr=m_diKeyboardDevice->Acquire();
	while( hr == DIERR_INPUTLOST )
    {     
       hr = m_diKeyboardDevice->Acquire();
    }
	return true;
}

bool CInputKeyboard::initialiseActionMapping(Element root)
{
	list<Element> keyboard=root.Children();
	//for each line
	for(list<Element>::iterator i=keyboard.begin(); i!=keyboard.end(); i++)
	{
		int indexAction=getIndexAction(i->Name());
		if(indexAction==-1)
			return false;

		std::string key=i->Content();
		m_actionMapArray[indexAction]=UI->getDirectInputValue(key);
	}
	return true;
}

void CInputKeyboard::doUpdate(void)
{
	//clear the buffer
	ZeroMemory(m_keys, 256*sizeof(BYTE));

	//get the inputs
	HRESULT hr=m_diKeyboardDevice->GetDeviceState( sizeof(m_keys), m_keys );

	if (FAILED(hr))
	{
		// acquire the device till success
		HRESULT hr=m_diKeyboardDevice->Acquire();
		while( hr == DIERR_INPUTLOST )
		{     
		   hr = m_diKeyboardDevice->Acquire();
		}

		if (FAILED(hr))
			 return;
		//get the inputs
		hr=m_diKeyboardDevice->GetDeviceState( sizeof(m_keys), m_keys );
	}

	if(m_keys[m_actionMapArray[eMoveForward]]&0x80)
	{
		WORLDMODEL->movePlayerForward(1);
	}
	if(m_keys[m_actionMapArray[eMoveBackward]]&0x80)
	{
		WORLDMODEL->movePlayerBackward(1);
	}
	if(m_keys[m_actionMapArray[eStrafeLeft]]&0x80)
	{
		WORLDMODEL->strafePlayerLeft(1);
	}
	if(m_keys[m_actionMapArray[eStrafeRight]]&0x80)
	{
		WORLDMODEL->strafePlayerRight(1);
	}
	if(m_keys[m_actionMapArray[eChangeCamera]]&0x80)
	{
		if(WORLDMODEL->getCameraMode()==WORLDMODEL->eModeFPS)
			WORLDMODEL->setCameraMode(WORLDMODEL->eModeTPS);
		else
			WORLDMODEL->setCameraMode(WORLDMODEL->eModeFPS);
	}
}
